package com.anlu.base.enums;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

public class SuperEnumUtil {
    private EnumCodeOf enumCodeOf;

    public SuperEnumUtil(EnumCodeOf enumCodeOf) {
        this.enumCodeOf = enumCodeOf;
    }

    private static ConcurrentHashMap<Class<?>, HashMap<String,EnumCodeOf>> enumMap = new ConcurrentHashMap<>(16);
    private static ConcurrentHashMap<Class<?>, HashMap<String,Enum>> enumCommonMap = new ConcurrentHashMap<>(16);


    public static <T,R extends Enum> R getEnum(Object code, Class<R>  clazz, Function<R,Object> getCode) {
       if(code == null){
           return null;
       }
        HashMap<String,Enum> codeMap = enumCommonMap.get(clazz);
        if(null != codeMap){
            return (R) codeMap.get(code.toString());
        }

        codeMap = new HashMap<>(8);

        try {
            R[] array = (R[]) clazz.asSubclass(Enum.class).getMethod("values").invoke(null);
            for(R sup:array){
                codeMap.put(getCode.apply(sup).toString(),sup);
            }

            enumCommonMap.put(clazz,codeMap);
        } catch (Exception e) {
            return null;
        }
        return (R) codeMap.get(code.toString());
    }


    public static <T extends EnumCodeOf>T codeOf(Object code,Class<T> clazz){
        if(null == code){
            return null;
        }
        HashMap<String,EnumCodeOf> codeMap = enumMap.get(clazz);
        if(null != codeMap){
            return (T) codeMap.get(code.toString());
        }

        codeMap = new HashMap<>(8);
        try {
         EnumCodeOf[] array =(EnumCodeOf[]) clazz.asSubclass(Enum.class).getMethod("values").invoke(null);
         for(EnumCodeOf superEnum:array){
            codeMap.put(superEnum.code().toString(), superEnum);
         }

            enumMap.put(clazz, codeMap);
        } catch (Exception e) {
            return null;
        }

        return (T) codeMap.get(code.toString());

    }



}
